package com.pacvue.handler;

import com.pacvue.exception.RateLimitException;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public abstract class AbstractRateLimiterAcquireTokenHandler implements RateLimiterAcquireTokenHandler {

    @Override
    public void acquire(String key, int capacity, double rate, long timeout) throws RateLimitException {
        long deadline = System.currentTimeMillis() + timeout * 1000L;
        int consecutiveFailures = 0;
        long baseWaitTime = 50; // 基础等待时间50ms
        
        while (System.currentTimeMillis() < deadline) {
            boolean acquire = this.tryAcquire(key, capacity, rate);
            if (acquire) {
                if (log.isDebugEnabled()) {
                    log.debug("成功获取令牌 - key: {}", key);
                }
                return;
            } else {
                consecutiveFailures++;
                // 动态计算等待时间：基础等待时间 + 连续失败次数 * 递增时间
                long waitTime = Math.min(baseWaitTime + consecutiveFailures * 10, 500);
                
                if (log.isDebugEnabled()) {
                    log.debug("获取令牌失败，等待{}ms后重试 - key: {}, 连续失败次数: {}", 
                             waitTime, key, consecutiveFailures);
                }
                
                try {
                    Thread.sleep(waitTime);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    throw new RateLimitException("线程被中断", e);
                } catch (Exception e) {
                    throw new RateLimitException("等待过程中发生异常: " + e.getMessage(), e);
                }
            }
        }
        
        if (log.isWarnEnabled()) {
            log.warn("等待超时，未能获取到令牌 - key: {}, timeout: {}s", key, timeout);
        }
        throw new RateLimitException("等待时间内未获取到令牌！");
    }

}
